package LeetCode.题库.简单;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 挚爱之夕
 * @date 2022-03-06 - 03 - 06 - 10:14
 * @Description 罗马数字包含以下七种字符: I， V， X， L，C，D 和 M。
 * 字符          数值
 * I             1
 * V             5
 * X             10
 * L             50
 * C             100
 * D             500
 * M             1000
 *例如， 罗马数字 2 写做II，即为两个并列的 1 。12 写做XII，即为X+II。
 * 27 写做XXVII, 即为XX+V+II。
 * 通常情况下，罗马数字中小的数字在大的数字的右边。但也存在特例，
 * 例如 4 不写做IIII，而是IV。
 * 数字 1 在数字 5 的左边，所表示的数等于大数 5 减小数 1 得到的数值 4 。
 * 同样地，数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况：
 * I可以放在V(5) 和X(10) 的左边，来表示 4 和 9。
 * X可以放在L(50) 和C(100) 的左边，来表示 40 和90。
 * C可以放在D(500) 和M(1000) 的左边，来表示400 和900。
 * 给定一个罗马数字，将其转换成整数。
 * @Version 简单
 */
public class _13罗马数字转整数 {
    static String s = "LVIII";
    @Test
    public void solve(){
        int res = romanToInt(s);
        System.out.println(res);
    }
    /*by me 使用HashMap(巨慢)*/
    public int romanToInt(String s) {
        Map<String, Integer> map = new HashMap<>();
        //基本字符
        map.put("I", 1);
        map.put("V", 5);
        map.put("X", 10);
        map.put("L", 50);
        map.put("C", 100);
        map.put("D", 500);
        map.put("M", 1000);
        //特殊情况
        map.put("IV", 4);
        map.put("IX", 9);
        map.put("XL", 40);
        map.put("XC", 90);
        map.put("CD", 400);
        map.put("CM", 900);

        int left = 0;
        int res = 0;
        String temp;
        while(left < s.length() - 1){
            //一次截取两个字符
            temp = s.substring(left, left + 2);
            System.out.println(temp);
            if(map.containsKey(temp)){  //特殊情况
                res += map.get(temp);
                left += 2;
            }else{  //基本字符
                res += map.get(temp.charAt(0) + "");
                left++;
            }

        }
        //是否还剩余一个字符
        if(left < s.length())
            res += map.get(s.charAt(left) + "");

        return res;
    }
    /*官方思路*/
    //每次累加当前数字，如果上一个数字大于当前，需要减去两倍的上一个数字
    public int romanToInt1(String s) {
        Map<Character, Integer> map = new HashMap<>();
        //基本字符
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);

        int preNum = 0, curNum;
        int res = 0;
        int p = 0;
        while(p < s.length()){
            curNum = map.get(s.charAt(p++));
            res += curNum;
            //特殊情况
            if(preNum < curNum){
                res -= 2 * preNum;
            }
            //记录这个数字作为下一个数字的上一个
            preNum = curNum;
        }
        return res;
    }
}
